package svc

import (
	"fmt"
	"jgt-oper/src/bll"
	"jgt-oper/src/context"
	"jgt-oper/src/logger"
	"jgt-oper/src/schema"
	"jgt-oper/src/util"
	"jgt-sdk/asapi"
	"net/http"

	"github.com/go-session/gear-session"
	"github.com/spf13/viper"
)

// Login 登录管理
type Login struct {
	LoginBll      *bll.Login      `inject:""`
	UserBll       *bll.User       `inject:""`
	EnterpriseBll *bll.Enterprise `inject:""`
}

// Verify 用户登录验证
func (a *Login) Verify(ctx *context.Context) error {
	var reqData schema.LoginInfo
	if err := ctx.ParseJSON(&reqData); err != nil {
		return ctx.ResErrBadRequest(err)
	}

	var result struct {
		Status string `json:"status"`
	}

	userID, err := a.LoginBll.Verify(ctx.GetTraceID(), reqData.Username, reqData.Password)
	if err != nil {
		ctx.WriteErrorLog(err)
		result.Status = "error"
		return ctx.ResSuccess(result)
	}

	item, err := a.UserBll.Get(userID)
	if err != nil || item == nil {
		if err != nil {
			ctx.WriteErrorLog(err)
		}
		result.Status = "error"
		return ctx.ResSuccess(result)
	}

	// 写入日志
	logger.Login(ctx.GetTraceID(), userID).Info("登入系统")

	// 更新session
	store, err := gearsession.Refresh(ctx.GearContext())
	if err != nil {
		ctx.WriteErrorLog(err)
		result.Status = "error"
		return ctx.ResSuccess(result)
	}

	store.Set(util.SessionUserIDKey, userID)
	store.Set(util.SessionUserTypeKey, item.UserType)
	store.Set(util.SessionEnterpriseIDKey, item.EnterpriseID)
	err = store.Save()
	if err != nil {
		ctx.WriteErrorLog(err)
		result.Status = "error"
		return ctx.ResSuccess(result)
	}

	result.Status = "ok"
	return ctx.ResSuccess(result)
}

// Logout 登出
func (a *Login) Logout(ctx *context.Context) error {
	if userID := ctx.GetUserID(); userID != "" {
		logger.Login(ctx.GetTraceID(), userID).Info("登出系统")
	}
	gearsession.FromContext(ctx.GearContext()).Flush()

	return ctx.ResSuccess("ok")
}

// GetUserInfo 查询当前用户的信息
func (a *Login) GetUserInfo(ctx *context.Context) error {
	item, err := a.UserBll.Get(ctx.GetUserID())
	if err != nil {
		return ctx.ResErrInternalServer(err)
	} else if item == nil {
		return ctx.ResErrBadRequest(fmt.Errorf("无效的用户"))
	}

	aitem, err := asapi.GetAPIWithTraceID(ctx.GetTraceID()).GetUserInfo(ctx.GetUserID())
	if err != nil {
		return ctx.ResErrInternalServer(err)
	} else if aitem == nil {
		return ctx.ResErrBadRequest(fmt.Errorf("无效的用户"))
	}

	username := aitem.UserName
	if username == "" {
		username = aitem.Tel
	}
	info := map[string]interface{}{
		"username":  username,
		"real_name": item.RealName,
	}

	if item.EnterpriseID != "" {
		eitem, err := a.EnterpriseBll.Get(item.EnterpriseID)
		if err == nil && eitem != nil {
			info["enterprise_name"] = eitem.Name
		}
	}

	return ctx.ResSuccess(info)
}

// QueryUserMenus 查询当前用户的菜单
func (a *Login) QueryUserMenus(ctx *context.Context) error {
	treeData, err := a.LoginBll.QuerySystemMenuByUserID(ctx.GetUserID(), viper.GetString("svc_system_code"), true)
	if err != nil {
		return ctx.ResErrInternalServer(err)
	} else if len(treeData) == 0 {
		return ctx.ResError(http.StatusUnauthorized, fmt.Errorf("访问受限，请联系管理员！"))
	}
	return ctx.ResSuccess(treeData)
}

// UpdatePassword 更新密码
func (a *Login) UpdatePassword(ctx *context.Context) error {
	var item schema.ModifyPassword
	if err := ctx.ParseJSON(&item); err != nil {
		return ctx.ResErrBadRequest(err)
	}

	err := a.UserBll.UpdatePassword(ctx.GetTraceID(), ctx.GetUserID(), item.OldPassword, item.Password)
	if err != nil {
		return ctx.ResErrInternalServer(err)
	}

	return ctx.ResOK()
}
